The objective of this study was to examine how non-autistic and autistic process social rewards, and whether participants would be able to learn whether two individuals were more similar or dissimilar to them. Prior to the fMRI scan, participants completed a survey of their interests (e.g. I am an animal lover). Using this survey, with over 200 responses, we matched other real participants to each other, such that every participant had a similar peer which shared 75% of the same interests, and a dissimilar peer which shared only 25% of the same interests. In the fMRI task, participants were shown an individuals name, either Shiloh or Charlie. These were the similar or dissimilar peers. For each trial, participants were first shown the peer’s name, then their own response to a survey question (e.g. animal lover indicating that the participant had responded that they love animals). Next, participants had to press a button to learn about the shown peer. The feedback consisted of a thumbs up with a “Me too!” message or a thumbs down with a “Not me!” message, indicating whether the peer had shared that interest or not. There was also a computer peer condition in which the computer gave 50% positive feedback as a “match” or “no match”.
This was an event-related design with four runs of the task.
library(dplyr)
library(tidyr)
library(ggplot2)
library(emmeans)
library(lmerTest)
require(gridExtra)
library(multcomp)
library(plyr)
library(sjPlot)
library(data.table)
library(stringi)
data_dir <- 'derivatives/task_socialreward/data/'
subj_df <- read.csv('participants.tsv', sep = '\t')
# Remove prefix from subject IDs
subj_df$participant_id<-gsub("sub-SCN","SCN_",as.character(subj_df$participant_id))
print(paste('Found ', length(subj_df$participant_id), ' participants'))
## [1] "Found 114 participants"
Task errors: The task programming had an error which would show the participant incorrect options for their own preferences (e.g. would show “like animals”, when the participant said they didn’t like animals). We will remove participants for which this occurred a lot (more than 5 trials).
# Create an empty dataframe to fill with all the participant data
rt_data <- data.frame(matrix(ncol = 6, nrow = 0))
# Name columns for the empty dataframe
colnames(rt_data) <- c('ParticipantID', 'Run', 'X', 'rating', 'ConditionName',
'Correct_RT')
# Import Data
for (subj in subj_df$participant_id) {
# Find data for all runs
run_files <- Sys.glob(paste(data_dir, subj, '/*-errors.csv', sep = ''))
# Loop through runs and combine into one df
for (run_file in run_files){
temp_run_data <- read.csv(run_file)
# Only include participant data if there were no task errors
if (sum(temp_run_data$redcap_v_task) == 0) {
# Filter for relevant columns
temp_run_data_fltr <- temp_run_data[,colnames(rt_data)]
# Append to entire df
rt_data <- rbind(rt_data, temp_run_data_fltr)
}
}
}
# Rename trial number column
names(rt_data)[names(rt_data) == 'X'] <- 'trial_num'
Add group (e.g. autistic, non-autistic) info to reaction time dataframe
rt_data <- merge(rt_data, subj_df,
by.x = 'ParticipantID', by.y = 'participant_id')
# Rename column
rt_data <- rt_data %>% rename_at('ParticipantID', ~'participant_id')
Create column for the peer conditions info and valence of feedback
rt_data <- rt_data %>% separate(ConditionName, c('Valence', 'Condition'))
rt_data$Valence <- gsub('LowReward','negative',as.character(rt_data$Valence))
rt_data$Valence <- gsub('HighReward','positive',as.character(rt_data$Valence))
Calculate the valence of the previous trial within each condition
# Create an empty column of NAs
rt_data$Valence_prev <- NA
for (subj in unique(rt_data$participant_id)) {
# Create a list of the runs for this participant
temp_run_list <- unique(rt_data[rt_data$participant_id == 'SCN_101', 'Run'])
for (run in temp_run_list) {
for (cond in c('SimPeer', 'DisPeer', 'Computer')) {
# Calculate the number of trials for a given condition per run per subject
temp_len <- length(rt_data[rt_data$participant_id == subj &
rt_data$Run == run &
rt_data$Condition == cond, 'Valence'])
# Create a list of the trial valences, excluding the first trial of that run
# since nothing was shown before that trial in the run
temp_val <- rt_data[rt_data$participant_id == subj &
rt_data$Run == run &
rt_data$Condition == cond, 'Valence'][1:temp_len-1]
# Fill in the previous trial valence for that condition
rt_data[rt_data$participant_id == subj &
rt_data$Run == run &
rt_data$Condition == cond, 'Valence_prev'] <- c(NA, temp_val)
}
}
}
Make group data an nominal data type
rt_data$group <- gsub('1','non-autistic',as.character(rt_data$group))
rt_data$group <- gsub('2','autistic',as.character(rt_data$group))
head(rt_data)
demo_info <- read.csv('misc/SCONNChildPacket-IdentifyingInfo_DATA_2024-05-13_1121.csv')
demo_info <- demo_info[demo_info$redcap_event_name == 'time_1_arm_1', ]
demo_info$record_id <- toupper(demo_info$record_id)
demo_info <- demo_info[which((demo_info$record_id %in% unique(rt_data$participant_id))==TRUE),]
mean(as.numeric(demo_info$child_exact_age), na.rm=TRUE)
## Warning in mean(as.numeric(demo_info$child_exact_age), na.rm = TRUE): NAs
## introduced by coercion
## [1] 13.05724
sd(as.numeric(demo_info$child_exact_age), na.rm=TRUE)
## Warning in is.data.frame(x): NAs introduced by coercion
## [1] 1.130972
table(demo_info$child_gender_lab_entered)
##
## 1 2 4 5
## 59 40 2 1
When a participant did not press the correct button, the feedback was “no data”. This occurred in two instances:
In both these instances, the participant was not paying attention and so we should exclude these trials. If this was the case for more than 20% of the run, then we should exclude data from the entire run.
# Find participant runs with more than 20% missed trials
exclude_subj_runs <- data.frame(participant_id = character(), Run = character(), stringsAsFactors = FALSE)
# Create a list of all subject IDs
subj_list <- unique(rt_data$participant_id)
for (subj in subj_list) {
# Filter for subject specific data
temp_subj_data <- rt_data[rt_data$participant_id == subj, ]
# Find runs per subject
temp_runs <- unique(temp_subj_data$Run)
for (run in temp_runs) {
# Filter for run specific data
temp_run_rt <- temp_subj_data[temp_subj_data$Run == run, 'Correct_RT']
# Calculate the percentage of missed trials
temp_na_perc <- sum(is.na(temp_run_rt)) / length(temp_run_rt)
# If more than 20% missed trials, exclude the participant run
if (temp_na_perc > 0.20) {
exclude_subj_runs[nrow(exclude_subj_runs) + 1,] <- c(subj, run)
}
}
}
print(paste('Excluding',nrow(exclude_subj_runs),'runs from',
length(unique(exclude_subj_runs$participant_id)),
'participants'))
## [1] "Excluding 5 runs from 4 participants"
Use the list of bad participant runs to remove that data from the larger dataframe
for (i in 1:nrow(exclude_subj_runs)) {
temp_drop_idx <- which(rt_data$participant_id == exclude_subj_runs[i, "participant_id"] &
rt_data$Run == exclude_subj_runs[i, "Run"])
rt_data <- rt_data[-temp_drop_idx, ]
}
With the remaining data, create column for missing trials. This might be interesting as it could be an indicator of learning. For example, if participants have learned who the dissimilar peer is, perhaps they would respond less for those trials than the similar peer trials. Accurate button presses will be coded as 1, and inaccurate will be coded as 0.
rt_data$accuracy <- 1
rt_data[is.na(rt_data$Correct_RT),'accuracy'] <- 0
table(rt_data$accuracy)
##
## 0 1
## 111 8352
Add run as a categorical variable (don’t end up using)
rt_data$Run.f <- factor(rt_data$Run)
Using method from Jones et al., 2014: “Reaction times to the cue after the wink occurred were z-score transformed to each individual’s mean and standard deviation after first removing outliers (defined as reaction times 3 standard deviations above or below the individual’s mean reaction time) and log transforming each reaction time to satisfy normality assumptions.”
# Create copy of the data
rt_data_mod <- data.frame(rt_data)
# Remove outliers greater than 3SD
#rt_data_mod[( rt_data_mod$ParticipantID %in% "SCN_101" & rt_data_mod$Correct_RT > 3*temp_sd),]
# Log transform
rt_data_mod$Correct_RT_log <- log(rt_data$Correct_RT)
# Create empty column for log zscored data
rt_data_mod$Correct_RT_logz <- NA
for (subj in subj_df$participant_id) {
# Calculate mean and SD
temp_subj_data <- filter(rt_data_mod, participant_id == subj)
temp_mean <- mean(temp_subj_data$Correct_RT_log, na.rm = TRUE)
temp_sd <- sd(temp_subj_data$Correct_RT_log, na.rm = TRUE)
rt_data_mod[(rt_data_mod$participant_id %in% subj),'Correct_RT_logz'] <- (rt_data_mod[(rt_data_mod$participant_id %in% subj),'Correct_RT_log'] - temp_mean)/temp_sd
}
plot1 <- ggplot(rt_data_mod, aes(x=Correct_RT)) + geom_histogram() + theme_classic()
plot2 <- ggplot(rt_data_mod, aes(x=Correct_RT_logz)) + geom_histogram() + theme_classic()
grid.arrange(plot1, plot2, ncol=2)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
The raw reaction times are not normally distributed and right-skewed. This may be a result of the task design where participants were given a window to view the interest and the peer condition, then a separate window to respond. So all participants were forced to view the condition for the same amount of time. After our log and z-transform, we have a normal distribution for the reaction times.
Lastly, we will set the similar peer condition as the reference group for the regression analyses
rt_data_mod$Condition <- relevel(factor(rt_data_mod$Condition), ref = "SimPeer")
rt_data_mod_typ <- filter(rt_data_mod, group == 'non-autistic')
print(paste("There are ",length(unique(rt_data_mod_typ$participant_id)),
" autistic participants"))
## [1] "There are 77 autistic participants"
Use a linear mixed-effects model to model both the fixed effects of our conditions of interest, and the random effects of the participants. An example of a random effect would be that some participants are just faster to respond in all conditions.
model_run_typ <- lmer(Correct_RT_logz ~ Run + (1 + Run | participant_id),
data = rt_data_mod_typ)
## boundary (singular) fit: see help('isSingular')
summary(model_run_typ)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: Correct_RT_logz ~ Run + (1 + Run | participant_id)
## Data: rt_data_mod_typ
##
## REML criterion at convergence: 16958.6
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -3.0848 -0.6828 -0.1236 0.5808 5.4321
##
## Random effects:
## Groups Name Variance Std.Dev. Corr
## participant_id (Intercept) 0.17697 0.4207
## Run 0.02872 0.1695 -1.00
## Residual 0.93445 0.9667
## Number of obs: 6081, groups: participant_id, 77
##
## Fixed effects:
## Estimate Std. Error df t value Pr(>|t|)
## (Intercept) 0.25869 0.05788 79.37397 4.469 2.58e-05 ***
## Run -0.10486 0.02284 78.45889 -4.590 1.66e-05 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr)
## Run -0.976
## optimizer (nloptwrap) convergence code: 0 (OK)
## boundary (singular) fit: see help('isSingular')
This analysis shows that participants are getting faster at responding throughout the task (B = -0.09, p = .0002).
ggplot(data = rt_data_mod_typ, aes(x=Run, y=Correct_RT_logz, group=Run)) +
geom_boxplot(outlier.shape = NA) +
geom_jitter(color='black', alpha=0.05) +
theme_classic()
## Warning: Removed 75 rows containing non-finite values (`stat_boxplot()`).
## Warning: Removed 75 rows containing missing values (`geom_point()`).
The box plots show this significant tread, and the individual response times for all participants.
Next, we will examine whether there are differences in reaction time to our peer conditions throughout the task. Again, the conditions were were getting feedback from a similar peer (75% positive feedback), dissimilar peer (25% positive feedback), or a random computer (50% positive feedback).
model_run_peer_typ <- lmer(Correct_RT_logz ~ Run*Condition + (1 + Run*Condition | participant_id),
data = rt_data_mod_typ)
## boundary (singular) fit: see help('isSingular')
## Warning: Model failed to converge with 1 negative eigenvalue: -2.7e+02
summary(model_run_peer_typ)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula:
## Correct_RT_logz ~ Run * Condition + (1 + Run * Condition | participant_id)
## Data: rt_data_mod_typ
##
## REML criterion at convergence: 16959.5
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -3.0433 -0.6796 -0.1171 0.5813 5.4850
##
## Random effects:
## Groups Name Variance Std.Dev. Corr
## participant_id (Intercept) 0.1611639 0.40145
## Run 0.0259667 0.16114 -1.00
## ConditionComputer 0.0020291 0.04505 0.43 -0.43
## ConditionDisPeer 0.0116478 0.10793 0.32 -0.32 0.13
## Run:ConditionComputer 0.0006077 0.02465 -0.32 0.32 -0.76
## Run:ConditionDisPeer 0.0031829 0.05642 -0.27 0.27 -0.10
## Residual 0.9300073 0.96437
##
##
##
##
##
## 0.51
## -1.00 -0.55
##
## Number of obs: 6081, groups: participant_id, 77
##
## Fixed effects:
## Estimate Std. Error df t value Pr(>|t|)
## (Intercept) 0.29620 0.07011 91.50242 4.225 5.65e-05 ***
## Run -0.12436 0.02696 88.54372 -4.612 1.34e-05 ***
## ConditionComputer -0.05836 0.07347 326.96845 -0.794 0.428
## ConditionDisPeer -0.05400 0.07452 469.29812 -0.725 0.469
## Run:ConditionComputer 0.05311 0.02729 201.17165 1.946 0.053 .
## Run:ConditionDisPeer 0.00552 0.02801 202.70730 0.197 0.844
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr) Run CndtnC CndtDP Rn:CnC
## Run -0.951
## CondtnCmptr -0.500 0.434
## ConditnDsPr -0.477 0.411 0.491
## Rn:CndtnCmp 0.449 -0.474 -0.909 -0.433
## Rn:CndtnDsP 0.417 -0.441 -0.439 -0.912 0.463
## optimizer (nloptwrap) convergence code: 0 (OK)
## boundary (singular) fit: see help('isSingular')
Accounting for the peer condition, task run had a significant impact on reaction times (B = -0.11, p < .001), such that participants were getting faster as the task went on. There was no significant main effect of peer condition. There is a trend for an interaction in which participants had faster reaction times throughout the task for the similar peer condition, in comparison to the computer control condition (B = .05, p = 0.05).
ggplot(data = rt_data_mod_typ, aes(x=factor(Run), y=Correct_RT_logz, fill=Condition)) +
geom_boxplot(outlier.shape = NA) +
geom_point(alpha=0.05, aes(fill=Condition),
position = position_jitterdodge(dodge.width = 0.8)) +
theme_classic()
## Warning: Removed 75 rows containing non-finite values (`stat_boxplot()`).
## Warning: Removed 75 rows containing missing values (`geom_point()`).
tab_model(model_run_peer_typ)
| Correct_RT_logz | |||
|---|---|---|---|
| Predictors | Estimates | CI | p |
| (Intercept) | 0.30 | 0.16 – 0.43 | <0.001 |
| Run | -0.12 | -0.18 – -0.07 | <0.001 |
| Condition [Computer] | -0.06 | -0.20 – 0.09 | 0.427 |
| Condition [DisPeer] | -0.05 | -0.20 – 0.09 | 0.469 |
|
Run × Condition [Computer] |
0.05 | -0.00 – 0.11 | 0.052 |
| Run × Condition [DisPeer] | 0.01 | -0.05 – 0.06 | 0.844 |
| Random Effects | |||
| σ2 | 0.93 | ||
| τ00 participant_id | 0.16 | ||
| τ11 participant_id.Run | 0.03 | ||
| τ11 participant_id.ConditionComputer | 0.00 | ||
| τ11 participant_id.ConditionDisPeer | 0.01 | ||
| τ11 participant_id.Run:ConditionComputer | 0.00 | ||
| τ11 participant_id.Run:ConditionDisPeer | 0.00 | ||
| ρ01 | -1.00 | ||
| 0.43 | |||
| 0.32 | |||
| -0.32 | |||
| -0.27 | |||
| N participant_id | 77 | ||
| Observations | 6081 | ||
| Marginal R2 / Conditional R2 | 0.018 / NA | ||
plot_model(model_run_peer_typ, type="pred", terms=c("Run","Condition"),
pred.type="re", ci.lvl=NA) +
theme_classic()
rt_data_mod_typ_means <- aggregate(Correct_RT_logz ~ participant_id * Run * Condition, rt_data_mod_typ, mean)
rt_data_mod_typ_means$Condition <- factor(rt_data_mod_typ_means$Condition,
levels=c('SimPeer', 'DisPeer', 'Computer'))
ggplot(data=rt_data_mod_typ_means, aes(x=factor(Run), y=Correct_RT_logz,
group=Condition, color=Condition)) +
geom_smooth(method='lm') +
geom_jitter(alpha=0.2) +
scale_color_manual(values=c('#1f77b4', '#ff7f0e', '#2ca02c'),
labels=c('Similar Peer', 'Dissimilar Peer', 'Computer')) +
theme_classic()
## `geom_smooth()` using formula = 'y ~ x'
Another way we can look at reaction time is to examine if reaction times would be effected by the valence of the previous trial from the same condition. For example, when considering to learn about “Shiloh” in the current trial, if Shiloh had given negative feedback in their last trial, perhaps the participants would be less motivated to learn about Shiloh in the current trial.
model_run_prev_val_typ <- lmer(Correct_RT_logz ~ Run*Valence_prev + (1 + Run*Valence_prev | participant_id),
data = rt_data_mod_typ)
## boundary (singular) fit: see help('isSingular')
summary(model_run_prev_val_typ)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: Correct_RT_logz ~ Run * Valence_prev + (1 + Run * Valence_prev |
## participant_id)
## Data: rt_data_mod_typ
##
## REML criterion at convergence: 14884.2
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -3.0998 -0.6858 -0.1211 0.5750 5.3218
##
## Random effects:
## Groups Name Variance Std.Dev. Corr
## participant_id (Intercept) 0.2023305 0.44981
## Run 0.0334201 0.18281 -0.99
## Valence_prevpositive 0.0008972 0.02995 -0.09 0.22
## Run:Valence_prevpositive 0.0037992 0.06164 -0.02 -0.12 -0.99
## Residual 0.9317805 0.96529
## Number of obs: 5326, groups: participant_id, 77
##
## Fixed effects:
## Estimate Std. Error df t value Pr(>|t|)
## (Intercept) 0.18393 0.06997 85.68025 2.629 0.01016 *
## Run -0.08387 0.02744 82.51443 -3.056 0.00302 **
## Valence_prevpositive -0.01995 0.06440 2533.92068 -0.310 0.75675
## Run:Valence_prevpositive 0.02147 0.02505 173.13446 0.857 0.39255
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr) Run Vlnc_p
## Run -0.956
## Vlnc_prvpst -0.471 0.413
## Rn:Vlnc_prv 0.404 -0.453 -0.885
## optimizer (nloptwrap) convergence code: 0 (OK)
## boundary (singular) fit: see help('isSingular')
ggplot(data = subset(rt_data_mod_typ, !is.na(Valence_prev)), aes(x=factor(Run), y=Correct_RT_logz, fill=Valence_prev)) +
geom_boxplot(outlier.shape = NA) +
geom_point(alpha=0.05, aes(fill=Valence_prev),
position = position_jitterdodge(dodge.width = 0.8)) +
theme_classic()
## Warning: Removed 68 rows containing non-finite values (`stat_boxplot()`).
## Warning: Removed 68 rows containing missing values (`geom_point()`).
The valence of the previous within condition trial did not have an impact on reaction times.
Since the previous analysis failed, maybe explicitly adding an interaction for the peer condition will have an impact on reaction times. For example, the valence of the trial might be more salient when it is a similar peer who previously gave you positive feedback or a dissimilar peer who previously gave you negative feedback.
model_run_prev_val_cond_typ <- lmer(Correct_RT_logz ~ Run*Condition*Valence_prev + (1 + Run*Condition*Valence_prev | participant_id),
data = rt_data_mod_typ)
## boundary (singular) fit: see help('isSingular')
## Warning: Model failed to converge with 3 negative eigenvalues: -1.1e+00
## -1.7e+00 -2.8e+02
summary(model_run_prev_val_cond_typ)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: Correct_RT_logz ~ Run * Condition * Valence_prev + (1 + Run *
## Condition * Valence_prev | participant_id)
## Data: rt_data_mod_typ
##
## REML criterion at convergence: 14887.2
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -3.0499 -0.6803 -0.1222 0.5716 5.2760
##
## Random effects:
## Groups Name Variance Std.Dev.
## participant_id (Intercept) 0.324365 0.5695
## Run 0.054317 0.2331
## ConditionComputer 0.100778 0.3175
## ConditionDisPeer 0.094511 0.3074
## Valence_prevpositive 0.135248 0.3678
## Run:ConditionComputer 0.021110 0.1453
## Run:ConditionDisPeer 0.009448 0.0972
## Run:Valence_prevpositive 0.032436 0.1801
## ConditionComputer:Valence_prevpositive 0.158842 0.3985
## ConditionDisPeer:Valence_prevpositive 0.091340 0.3022
## Run:ConditionComputer:Valence_prevpositive 0.036239 0.1904
## Run:ConditionDisPeer:Valence_prevpositive 0.026181 0.1618
## Residual 0.919062 0.9587
## Corr
##
## -1.00
## -0.63 0.63
## -0.59 0.59 0.89
## -0.67 0.67 0.98 0.86
## 0.61 -0.61 -0.95 -0.73 -0.95
## 0.65 -0.65 -0.89 -0.99 -0.86 0.74
## 0.67 -0.67 -0.97 -0.93 -0.98 0.88 0.92
## 0.69 -0.69 -0.91 -0.66 -0.93 0.93 0.68 0.85
## 0.63 -0.63 -0.84 -0.67 -0.89 0.79 0.66 0.87 0.91
## -0.69 0.69 0.97 0.76 0.96 -0.99 -0.78 -0.90 -0.97 -0.84
## -0.69 0.69 0.71 0.54 0.81 -0.71 -0.53 -0.78 -0.85 -0.96 0.76
##
## Number of obs: 5326, groups: participant_id, 77
##
## Fixed effects:
## Estimate Std. Error df
## (Intercept) 0.155364 0.122580 91.198882
## Run -0.084630 0.046851 91.196906
## ConditionComputer 0.109083 0.135750 147.197337
## ConditionDisPeer -0.016182 0.126896 215.436562
## Valence_prevpositive 0.023243 0.129310 137.885281
## Run:ConditionComputer -0.001839 0.051326 96.347618
## Run:ConditionDisPeer 0.005078 0.046416 228.821324
## Run:Valence_prevpositive 0.009203 0.049933 90.617003
## ConditionComputer:Valence_prevpositive -0.164720 0.170986 101.172368
## ConditionDisPeer:Valence_prevpositive 0.037465 0.176330 290.960767
## Run:ConditionComputer:Valence_prevpositive 0.055041 0.064996 81.619456
## Run:ConditionDisPeer:Valence_prevpositive -0.035710 0.066778 159.833463
## t value Pr(>|t|)
## (Intercept) 1.267 0.2082
## Run -1.806 0.0742 .
## ConditionComputer 0.804 0.4229
## ConditionDisPeer -0.128 0.8986
## Valence_prevpositive 0.180 0.8576
## Run:ConditionComputer -0.036 0.9715
## Run:ConditionDisPeer 0.109 0.9130
## Run:Valence_prevpositive 0.184 0.8542
## ConditionComputer:Valence_prevpositive -0.963 0.3377
## ConditionDisPeer:Valence_prevpositive 0.212 0.8319
## Run:ConditionComputer:Valence_prevpositive 0.847 0.3996
## Run:ConditionDisPeer:Valence_prevpositive -0.535 0.5936
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr) Run CndtnC CndtDP Vlnc_p Rn:CnC Rn:CDP Rn:Vl_ CnC:V_
## Run -0.937
## CondtnCmptr -0.728 0.660
## ConditnDsPr -0.769 0.694 0.682
## Vlnc_prvpst -0.788 0.719 0.691 0.724
## Rn:CndtnCmp 0.675 -0.719 -0.911 -0.614 -0.641
## Rn:CndtnDsP 0.711 -0.756 -0.623 -0.915 -0.661 0.665
## Rn:Vlnc_prv 0.736 -0.785 -0.637 -0.671 -0.916 0.688 0.717
## CndtnCmp:V_ 0.606 -0.554 -0.803 -0.537 -0.756 0.740 0.493 0.686
## CndtnDsP:V_ 0.557 -0.504 -0.487 -0.699 -0.710 0.446 0.641 0.641 0.542
## Rn:CndtC:V_ -0.577 0.616 0.743 0.504 0.707 -0.816 -0.544 -0.761 -0.913
## Rn:CndDP:V_ -0.540 0.575 0.448 0.631 0.655 -0.490 -0.689 -0.703 -0.503
## CDP:V_ R:CC:V
## Run
## CondtnCmptr
## ConditnDsPr
## Vlnc_prvpst
## Rn:CndtnCmp
## Rn:CndtnDsP
## Rn:Vlnc_prv
## CndtnCmp:V_
## CndtnDsP:V_
## Rn:CndtC:V_ -0.494
## Rn:CndDP:V_ -0.910 0.542
## optimizer (nloptwrap) convergence code: 0 (OK)
## boundary (singular) fit: see help('isSingular')
ggplot(data = subset(rt_data_mod_typ, !is.na(Valence_prev)), aes(x=factor(Run), y=Correct_RT_logz, fill=Condition, alpha=Valence_prev)) +
geom_boxplot(outlier.shape = NA) +
theme_classic()
## Warning: Using alpha for a discrete variable is not advised.
## Warning: Removed 68 rows containing non-finite values (`stat_boxplot()`).
Makes no difference.
In the later runs, is there a difference in reaction time between the similar and dissimilar peer conditions? How many participants show this learning effect?
rt_means_subj_cond_run_typ <- ddply(rt_data_mod_typ, c('participant_id','Condition','Run'),
summarise,
mean=mean(Correct_RT, na.rm=TRUE))
Calculate the difference in RT for similar and dissimilar peer conditions at run 4
r4_peer_diff_typ <- data.frame(matrix(ncol = 2, nrow = 0))
# Name columns for the empty dataframe
colnames(r4_peer_diff_typ) <- c('ParticipantID', 'sim_dis_RT')
for (subj in unique(rt_means_subj_cond_run_typ$participant_id)) {
temp_subj_data <- rt_means_subj_cond_run_typ[rt_means_subj_cond_run_typ$participant_id == subj, ]
temp_last_run <- temp_subj_data$Run[length(unique(temp_subj_data$Run))]
temp_run_data <- temp_subj_data[temp_subj_data$Run == temp_last_run, ]
temp_diff <- temp_run_data[temp_run_data$Condition == 'SimPeer', 'mean'] - temp_run_data[temp_run_data$Condition == 'DisPeer', 'mean']
r4_peer_diff_typ[nrow(r4_peer_diff_typ) + 1,] = c(subj,temp_diff)
}
r4_peer_diff_typ$sim_dis_RT <- as.numeric(r4_peer_diff_typ$sim_dis_RT)
ggplot(r4_peer_diff_typ, aes(x=sim_dis_RT)) + geom_histogram() + theme_classic()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
prop_learn <- nrow(r4_peer_diff_typ[r4_peer_diff_typ$sim_dis_RT < 0, ]) / nrow(r4_peer_diff_typ)
print(paste(round(prop_learn, 4)*100, '% of participants had faster RTs for similar peers than dissimilar peers for their last run.'))
## [1] "46.75 % of participants had faster RTs for similar peers than dissimilar peers for their last run."
t.test(r4_peer_diff_typ$sim_dis_RT, alternative = "two.sided", var.equal = FALSE)
##
## One Sample t-test
##
## data: r4_peer_diff_typ$sim_dis_RT
## t = -0.32665, df = 76, p-value = 0.7448
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
## -0.02933101 0.02106560
## sample estimates:
## mean of x
## -0.004132705
Note that previous valence here is the previous valence of the trial within the same condition.
rt_means_subj_pval_run_typ <- ddply(rt_data_mod_typ, c('participant_id','Valence_prev','Run'),
summarise,
mean=mean(Correct_RT, na.rm=TRUE))
# Remove rows with NA
rt_means_subj_pval_run_typ <- rt_means_subj_pval_run_typ[complete.cases(rt_means_subj_pval_run_typ), ]
Calculate the difference in RT for similar and dissimilar peer conditions at run 4
# Create a new column for for previous valence
r4_peer_diff_typ$pos_neg_RT <- NA
for (subj in unique(rt_means_subj_pval_run_typ$participant_id)) {
temp_subj_data <- rt_means_subj_pval_run_typ[rt_means_subj_pval_run_typ$participant_id == subj, ]
temp_last_run <- temp_subj_data$Run[length(unique(temp_subj_data$Run))]
temp_run_data <- temp_subj_data[temp_subj_data$Run == temp_last_run, ]
temp_diff <- temp_run_data[temp_run_data$Valence_prev == 'positive', 'mean'] - temp_run_data[temp_run_data$Valence_prev == 'negative', 'mean']
r4_peer_diff_typ[r4_peer_diff_typ$ParticipantID == subj, 'pos_neg_RT'] = temp_diff
}
r4_peer_diff_typ$pos_neg_RT <- as.numeric(r4_peer_diff_typ$pos_neg_RT)
ggplot(r4_peer_diff_typ, aes(x=pos_neg_RT)) + geom_histogram() + theme_classic()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
prop_learn <- nrow(r4_peer_diff_typ[r4_peer_diff_typ$pos_neg_RT < 0, ]) / nrow(r4_peer_diff_typ)
print(paste(round(prop_learn, 4)*100, '% of participants had faster RTs for trials that were precided by a positive outcome than negative outcomes, for their last run.'))
## [1] "42.86 % of participants had faster RTs for trials that were precided by a positive outcome than negative outcomes, for their last run."
t.test(r4_peer_diff_typ$pos_neg_RT, alternative = "two.sided", var.equal = FALSE)
##
## One Sample t-test
##
## data: r4_peer_diff_typ$pos_neg_RT
## t = 1.1747, df = 76, p-value = 0.2438
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
## -0.01063827 0.04123292
## sample estimates:
## mean of x
## 0.01529732
A survey was completed before the fMRI task and afterwards to gauge the participant’s perceived similarity to the similar and dissimilar peer.
sim_learners <- read.csv('derivatives/pre_post_task_survey/participants-task-sim_learn.csv')
# Remove prefix from subject IDs
sim_learners$participant_id<-gsub("sub-SCN","SCN_",as.character(sim_learners$participant_id))
head(sim_learners)
Filter for participants who learned the similar peer
rt_data_mod_typ_sim_learn <- filter(rt_data_mod_typ,
rt_data_mod_typ$participant_id %in% sim_learners$participant_id)
head(rt_data_mod_typ_sim_learn)
model_run_peer_typ_sim_learn <- lmer(Correct_RT_logz ~ Run*Condition + (1 + Run*Condition | participant_id),
data = rt_data_mod_typ_sim_learn)
## boundary (singular) fit: see help('isSingular')
summary(model_run_peer_typ_sim_learn)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula:
## Correct_RT_logz ~ Run * Condition + (1 + Run * Condition | participant_id)
## Data: rt_data_mod_typ_sim_learn
##
## REML criterion at convergence: 14214
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -3.0679 -0.6686 -0.1173 0.5907 5.4965
##
## Random effects:
## Groups Name Variance Std.Dev. Corr
## participant_id (Intercept) 0.1854457 0.43063
## Run 0.0299937 0.17319 -1.00
## ConditionComputer 0.0084670 0.09202 0.06 -0.10
## ConditionDisPeer 0.0274943 0.16581 0.05 -0.13 0.85
## Run:ConditionComputer 0.0004264 0.02065 -0.07 0.01 -0.32
## Run:ConditionDisPeer 0.0041870 0.06471 -0.07 0.12 -0.95
## Residual 0.9224672 0.96045
##
##
##
##
##
## 0.23
## -0.93 0.06
##
## Number of obs: 5106, groups: participant_id, 63
##
## Fixed effects:
## Estimate Std. Error df t value Pr(>|t|)
## (Intercept) 0.324096 0.079085 70.234935 4.098 0.00011 ***
## Run -0.132689 0.030489 69.800188 -4.352 4.52e-05 ***
## ConditionComputer -0.096848 0.080470 175.718433 -1.204 0.23039
## ConditionDisPeer -0.042535 0.082563 139.578030 -0.515 0.60724
## Run:ConditionComputer 0.061985 0.029484 198.593097 2.102 0.03679 *
## Run:ConditionDisPeer 0.001792 0.030583 164.856296 0.059 0.95334
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr) Run CndtnC CndtDP Rn:CnC
## Run -0.953
## CondtnCmptr -0.492 0.422
## ConditnDsPr -0.477 0.398 0.509
## Rn:CndtnCmp 0.451 -0.477 -0.901 -0.430
## Rn:CndtnDsP 0.426 -0.437 -0.468 -0.912 0.476
## optimizer (nloptwrap) convergence code: 0 (OK)
## boundary (singular) fit: see help('isSingular')
ggplot(data = rt_data_mod_typ_sim_learn, aes(x=factor(Run), y=Correct_RT_logz,
fill=Condition)) +
geom_boxplot(outlier.shape = NA) +
geom_point(alpha=0.05, aes(fill=Condition),
position = position_jitterdodge(dodge.width = 0.8)) +
theme_classic()
## Warning: Removed 60 rows containing non-finite values (`stat_boxplot()`).
## Warning: Removed 60 rows containing missing values (`geom_point()`).
rt_data_mod_typ_sim_learn_means <- aggregate(Correct_RT_logz ~ participant_id * Run * Condition, rt_data_mod_typ_sim_learn, mean)
rt_data_mod_typ_sim_learn_means$Condition <- factor(rt_data_mod_typ_sim_learn_means$Condition,
levels=c('SimPeer', 'DisPeer', 'Computer'))
ggplot(data=rt_data_mod_typ_sim_learn_means, aes(x=factor(Run), y=Correct_RT_logz,
group=Condition, color=Condition)) +
geom_smooth(method='lm') +
geom_jitter(alpha=0.2) +
scale_color_manual(values=c('#1f77b4', '#ff7f0e', '#2ca02c'),
labels=c('Similar Peer', 'Dissimilar Peer', 'Computer')) +
theme_classic()
## `geom_smooth()` using formula = 'y ~ x'